use std::time::Duration;
use std::usize::MIN;
use cpal::{BufferSize, Device, Host, SampleFormat, SampleRate, StreamConfig};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use tokio::sync::mpsc::Receiver;
use tokio::time::sleep;

pub(crate) fn init_cpal() {
    let host = cpal::default_host();
    println!("当前音频后端: {}", host.id().name());

    for device in host.input_devices().unwrap() {
        println!("input devices: {:?}", device.name());
    }

    for device in host.output_devices().unwrap() {
        println!("output devices: {:?}", device.name());
    }

    let defalut_input = host.default_input_device().unwrap();
    println!("defalut input: {:?}", defalut_input.name());

    let defalut_output = host.default_output_device().unwrap();
    println!("defalut output: {:?}", defalut_output.name());

    let supported_config = defalut_output.default_output_config().unwrap();
    let format = supported_config.sample_format();
    println!("  缓冲区大小范围: {:?}", supported_config.buffer_size());
    let config: StreamConfig = supported_config.into();
    println!(
        "config: format: {:?}, sample_rate: {:?}, channels: {:?}, buffer_size: {:?}",
        format, config.sample_rate, config.channels, config.buffer_size
    );
}

/* 初始化一个默认输出 */
pub(crate) fn init_defalut_output() -> Result<(Device, StreamConfig), anyhow::Error>{
    let host = cpal::default_host();
    let defalut_output = host.default_output_device().unwrap();
    let config:StreamConfig  = defalut_output.default_output_config()?.into();
    Ok((defalut_output, config))
}

pub(crate) async fn play_stream<T>(
    device: Device,
    config:&StreamConfig,
    mut tx: Receiver<Vec<T>>,
    dur_time:u64,
) -> Result<(), anyhow::Error>
where T: From<f32> + From<i16> + From<u16> + Clone + Copy + cpal::SizedSample + Send + 'static+ std::fmt::Debug{

    let mut position: usize = 0;
    let mut local_samples: Vec<T> = Vec::with_capacity(4096);
    
    let stream = device.build_output_stream(
        config,
        move |data: &mut [T], _| {
            // println!("datas.len: {}", data.len());
            
            // let data_len = data.len();
            // if let Ok(samples) = tx.try_recv() {
            //     println!("samples.len: {}", samples.len());
            //     let samples_len = samples.len();
            //     let min_len = samples_len.min(data_len);
            //     data[..min_len].copy_from_slice(&samples[..min_len])
            // }else {
            //     println!("try_recv.len: kong");
            // }

            let data_len = data.len();
            let local_len = local_samples.len();
            let sy_len = local_len - position;
            if sy_len < data_len {
                if sy_len > 0 {
                    data[..sy_len].copy_from_slice(&local_samples[position..]);
                    position = 0;
                }
                read_stream_data(&mut local_samples, &mut tx,  data, data_len, sy_len,&mut position);
            } else {
                let end_len = position + data_len;
                data[..data_len].copy_from_slice(&local_samples[position..end_len]);
                position = end_len;
            }
        },
        |err| {
            eprintln!("播放错误: {}", err);
        },
        None,
    )?;
    stream.play()?;
    sleep(Duration::from_millis(dur_time)).await;
    Ok(())
}

#[inline]
fn read_stream_data<T>(
    local_samples: &mut Vec<T>,
    tx: &mut Receiver<Vec<T>>,
    data: &mut [T],
    data_len: usize,
    sy_len: usize,
    position: &mut usize,
)
where T: From<f32> + From<i16> + From<u16> + Clone + Copy + cpal::SizedSample + Send + 'static + std::fmt::Debug{
    if let Ok(samples) = tx.try_recv() {
        let p = data_len - sy_len;
        let l_len = samples.len();
        if p > l_len {
            let d_l_len = sy_len + l_len;
            data[sy_len..d_l_len].copy_from_slice(&samples[..l_len]);
            *position = 0;
            read_stream_data(
                local_samples,
                tx,
                data,
                data_len,
                data_len - d_l_len,
                position,
            );
        }else
        {
            *local_samples = samples;
            data[sy_len..data_len].copy_from_slice(&local_samples[..p]);
            *position = p;
        }
    } else {
        println!("返回数据为空");
        *position = 0;
        data[sy_len..data_len].fill(0.0.into());
        *local_samples = vec![];
    }
}


/* 录音 */
pub(crate) fn record_cpal_sound() -> Result<(), anyhow::Error>{
    let host = cpal::default_host();

    let input_device = host.default_input_device().ok_or(anyhow::Error::msg("No input device available"))?;

   let configs = input_device.supported_input_configs()?;

    for config in configs {
        println!(
            "  {:?}, sample rate: {}-{} Hz",
            config,
            config.min_sample_rate().0,
            config.max_sample_rate().0
        );
    }
    
    // let config = input_device.default_input_config()?;
    // 
    // println!("config: {:?}", config);
    // 
    // let s_config = StreamConfig{
    //     channels:2,
    //     sample_rate:SampleRate(16000),
    //     buffer_size:BufferSize::Default,
    // };
    // 
    // // 4. 创建输入流
    // let stream = input_device.build_input_stream(
    //     &s_config,
    //     move |data: &[f32], _: &cpal::InputCallbackInfo| {
    //         // 音频数据回调处理
    //         println!("Got {} samples", data.len());
    //     },
    //     |err| eprintln!("Stream error: {}", err),
    //     None // 无超时
    // )?;
    // 
    // // 5. 启动流
    // stream.play()?;
    // 
    // // 保持程序运行
    // std::thread::sleep(std::time::Duration::from_secs(2));
    
    Ok(())
}





